package MotorGrafico;

import java.awt.Point;
import java.util.Iterator;
import java.util.List;

import util.Constantes;
import Jplay.Animation;
import Jplay.GameImage;
import Jplay.Scene;
import Jplay.TileInfo;

/**
 * Classe respons�vel pelo tabuleiro.
 * 
 * @author Gefersom C. Lima
 * */

public class Tabuleiro extends Scene {

	/**
	 * Respons�vel por carregar a cena na mem�ria e por criar as listas de pe�as
	 * removidas.
	 */
	Animation imgPossivelJogada;
	Animation imgJogadaSugerida;
	GameImage imgPecaSelecionada;
	GameImage imgCasaSobMouse;
	List casasPossiveisJogadas;
	List casasJogadasSugeridas;

	/**
	 * Construtor da classe.
	 */
	
	public Tabuleiro(int xDeslocamento, int yDeslocamento) {
		this();
		this.setDrawStartPos(xDeslocamento, yDeslocamento);
	}
	
	public Tabuleiro clone(){
		Tabuleiro tab = new Tabuleiro();
		int[][] aux = tab.getTileMatrix();
		for (int a = 0; a<aux.length; a++)
			for (int b=0; b< aux.length; b++)
				tab.setPeca(this.getPeca(a,b), a, b);
		
		return tab;
	}

	public Tabuleiro() {
		super();
		super.loadFromFile(Constantes.PATH_SCENE);
		imgPecaSelecionada = new GameImage(
				Constantes.IMG_TABULEIRO_SELECAO_PECA);
		imgCasaSobMouse = new GameImage(Constantes.IMG_TABULEIRO_SELECAO_CASA);
		imgPossivelJogada = new Animation(
				Constantes.IMG_TELA_JOGO_POSSIVEL_JOGADA, 2);
		imgJogadaSugerida = new Animation(
				Constantes.IMG_TELA_JOGO_POSSIVEL_JOGADA, 2);
		casasPossiveisJogadas = null;
		casasJogadasSugeridas = null;

		retirarSelecaoPeca();
	}

	/**
	 * Remove uma pe�a do tabuleiro.
	 * 
	 * @param linha
	 *            lihha na matriz de pe�as
	 * @param coluna
	 *            coluna na matriz de pe�as
	 */

	public void setPeca(int tipoPeca, int linha, int coluna) {
		super.changeTile(linha, coluna, tipoPeca);
	}

	/**
	 * Retorna a id da pe�a que est� na posic�o (linha,coluna).
	 * 
	 * @param linha
	 *            Linha da matriz.
	 * @param coluna
	 *            Coluna da matriz.
	 * @return
	 */
	public int getPeca(int linha, int coluna) {
		return super.getTile(linha, coluna).id;
	}

	/**
	 * Remove uma pe�a do tabuleiro.
	 * 
	 * @param linha
	 *            Linha onde a pe�a est� contida na matriz.
	 * @param coluna
	 *            Coluna onde a pe�a est� contida na matriz.
	 */

	public void removerPeca(int linha, int coluna) {
		TileInfo tile = super.getTile(linha, coluna);
		tile.id = Constantes.ESTADO_VAZIO;// Ao setar o id como vazio o tile
											// n�o ser� mais desenhado na
											// tela.
	}

	/**
	 * Retorna o um inst�ncia da classe �ndice que cont�m as posi��es (i,j) da
	 * casa que est� sob o mouse. Se o mouse estiverfora da �rea das pe�as
	 * retorna null.
	 * 
	 * @param posicaoMouse
	 *            Posi��o do mouse na tela.
	 * @return Indice
	 */
	// Todas as pecas possuem a mesma largura e altura
	public Indice getCasaSobMouse(Point posicaoMouse) {
		TileInfo tile = super.getTile(0, 0);

		int deslocaX = super.getDrawStartX();
		int deslocaY = super.getDrawStartY();

		int coluna = 0;
		int linha = 0;

		int altura = tile.height;
		int alturaTotal = 0;
		int largura = tile.width;
		int larguraTotal = 0;

		// Somando a largura de todas as pe�as temos a larguraTotal
		larguraTotal = super.getDrawStartX() + largura
				* Constantes.QUANT_LINHAS_TABULEIRO;
		if (posicaoMouse.x <= deslocaX || posicaoMouse.x >= larguraTotal)
			return null;

		// Somando a altura de todas as pe�as temos a alturaTotal
		alturaTotal = deslocaY + altura * Constantes.QUANT_COLUNAS_TABULEIRO;
		if (posicaoMouse.y <= deslocaY || posicaoMouse.y >= alturaTotal)
			return null;

		linha = (posicaoMouse.y + deslocaX) / tile.width;
		coluna = (posicaoMouse.x + deslocaY) / tile.height;

		return new Indice(linha, coluna);
	}

	/**
	 * Apresenta uma borda em volta da casa selecionada.
	 * 
	 * @param linha
	 *            Linha onde a pe�a est� contida na matriz.
	 * @param coluna
	 *            Coluna onde a pe�a est� contida na matriz.
	 */

	public void selecionarCasa(int linha, int coluna) {
		TileInfo tile = super.getTile(linha, coluna);
		imgCasaSobMouse.setPosition(coluna * tile.width + getDrawStartX(),
				linha * tile.width + getDrawStartY());
	}

	/**
	 * Apresenta uma borda em volta da pe�a selecionada.
	 * 
	 * @param linha
	 *            Linha onde a pe�a est� contida na matriz.
	 * @param coluna
	 *            Coluna onde a pe�a est� contida na matriz.
	 */

	public void selecionarPeca(int linha, int coluna) {
		TileInfo tile = super.getTile(linha, coluna);
		imgPecaSelecionada
				.setPosition(coluna * tile.height, linha * tile.width);
	}

	/**
	 * Desenha as imagens que destacam as casa de possiveis jogadas.
	 * 
	 * @param jogadas
	 *            - Lista contendo os �ndices das casas de poss�veis jogadas.
	 * @param imagem
	 *            - Imagem a ser usada para representar o destaque.
	 */
	private void desenharCasaJogadas(List jogadas, Animation imagem) {
		if (jogadas != null) {

			Iterator<Indice> i = jogadas.iterator();

			while (i.hasNext()) {
				Indice ind = i.next();
				TileInfo tile = getTile(ind.i, ind.j);
				int y = tile.height * ind.i;
				int x = tile.width * ind.j;
				imagem.x = x;
				imagem.y = y;
				if (ind.i % 2 == 0 && ind.j % 2 == 0)
					imagem.setCurrFrame(0);
				else
					imagem.setCurrFrame(1);
				imagem.draw();
			}
		}

	}

	/**
	 * Desenha as imagens do tabuleiro na tela.
	 */

	public void draw() {
		super.draw();
		desenharCasaJogadas(casasPossiveisJogadas, imgPossivelJogada);
		desenharCasaJogadas(casasJogadasSugeridas, imgJogadaSugerida);
		imgPecaSelecionada.draw();
		imgCasaSobMouse.draw();
	}

	/**
	 * Seta a lista que ser� usada para a pintura das casa de poss�veis jogadas.
	 * 
	 * @param listaDeCasas
	 *            - Lista contendo os �ndices das casas de poss�veis jogadas.
	 */
	public void pintarCasasDePossiveisJogadas(List<Indice> listaDeCasas) {
		this.casasPossiveisJogadas = listaDeCasas;
	}

	/**
	 * Seta a lista que ser� usada para a pintura das casa de jogadas sugeridas
	 * pela IA.
	 * 
	 * @param listaDeCasas
	 *            - Lista contendo os �ndices das casas sugeridas.
	 */
	public void pintarCasasSugereJogada(List<Indice> listaDeCasas) {
		this.casasJogadasSugeridas = listaDeCasas;
	}

	/**
	 * Verifica se uma pe�a � negra.
	 * 
	 * @param idPeca
	 *            Id da pe�a a ser verificada.
	 * @return true se a pe�a � negra, false ao contr�rio.
	 */

	public static boolean isPecaNegra(int idPeca) {

		if (idPeca >= 1 && idPeca <= 6)
			return true;
		return false;
	}

	/**
	 * Verifica se uma pe�a � branca.
	 * 
	 * @param idPeca
	 *            Id da pe�a a ser verificada.
	 * @return true se a pe�a � negra, false ao contr�rio.
	 */

	public static boolean isPecaBranca(int idPeca) {

		if (idPeca >= 7 && idPeca <= 12)
			return true;
		return false;
	}

	/**
	 * Retira a sele��o de qualquer pe�a que esteja selecionada no momento de
	 * chamada do m�todo.
	 */
	public void retirarSelecaoPeca() {
		imgPecaSelecionada.setPosition(-imgPecaSelecionada.width,
				-imgPecaSelecionada.height);
	}

	/**
	 * Verifica se a posis�o (linha,coluna) da matriz de pe�as est� ocupada por
	 * alguma pe�a.
	 * 
	 * @param linha
	 *            lihha na matriz de pe�as.
	 * @param coluna
	 *            coluna na matriz de pe�as.
	 * @return true Posi��o ocupada. false Ao contr�rio.
	 */
	public boolean isPosicaoVazia(int linha, int coluna) {
		TileInfo tile = super.getTile(linha, coluna);
		return tile.id == Constantes.ESTADO_VAZIO;
	}

	/**
	 * Imprime no console os valores armazenados na matrix que representa o
	 * tabuleiro no momento da chamada do m�todo.
	 */
	public void imprIndice() {
		String aux = "";
		int[][] matrix = super.getTileMatrix();
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++){
				if (matrix[i][j]<10){
					aux = "0";
				} else {
					aux = "";
				}
				System.out.print(aux+matrix[i][j] + " ");
			}
			System.out.println("");
		}
	}

	/**
	 * Imprime no console os nomes de cada uma das pe�as de acordo com a sua
	 * posi��o na matrix que representa o tabuleiro.
	 */
	public void impr() {
		int[][] matrix = super.getTileMatrix();
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				if (matrix[i][j] == Constantes.BLACK_BISPO
						|| matrix[i][j] == Constantes.WHITE_BISPO)
					System.out.print(" Bispo (" + matrix[i][j] + ")");
				else if (matrix[i][j] == Constantes.BLACK_CAVALO
						|| matrix[i][j] == Constantes.WHITE_CAVALO)
					System.out.print(" Cavalo (" + matrix[i][j] + ")");
				else if (matrix[i][j] == Constantes.BLACK_PEAO
						|| matrix[i][j] == Constantes.WHITE_PEAO)
					System.out.print(" Peao (" + matrix[i][j] + ")");
				else if (matrix[i][j] == Constantes.BLACK_RAINHA
						|| matrix[i][j] == Constantes.WHITE_RAINHA)
					System.out.print(" Rainha (" + matrix[i][j] + ")");
				else if (matrix[i][j] == Constantes.BLACK_REI
						|| matrix[i][j] == Constantes.WHITE_REI)
					System.out.print(" Rei (" + matrix[i][j] + ")");
				else if (matrix[i][j] == Constantes.BLACK_TORRE
						|| matrix[i][j] == Constantes.WHITE_TORRE)
					System.out.print(" Torre (" + matrix[i][j] + ")");
			}
			System.out.println("");
		}
	}

}
